﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ComparisonGraph
{
    public class RunTimes
    {
        public TimeSpan[] runTimes;// { public get; private set; }
        public string algorithm;//{ public get; private set; }
        public int[] arraySizes;// { public get; private set; }
        public delegate int[] Sort(int[] array);
        public delegate List<int> Match(string pattern, string text);

        /// <summary>
        /// Constructor that also sorts the passed arrays and records the times
        /// </summary>
        /// <param name="SortAlgorithm"></param>
        /// <param name="unsortedArrays"></param>
        public RunTimes(Sort SortAlgorithm, int[][] unsortedArrays)
        {
            algorithm = SortAlgorithm.Method.DeclaringType.Name; //find the name of the sort algorithm;
            runTimes = new TimeSpan[unsortedArrays.Length];
            runTimes = GetTimes(SortAlgorithm, unsortedArrays);
            arraySizes = new int[unsortedArrays.GetLength(0)];
            for (int i = 0; i < unsortedArrays.GetLength(0); i++)
            {
                arraySizes[i] = unsortedArrays[i].Length;
            }
        }

        /// <summary>
        /// Constructor that also Matches the passed patterns to the passed text and records the times
        /// </summary>
        /// <param name="MatchAlgorithm"></param>
        /// <param name="patterns"></param>
        /// <param name="text"></param>
        public RunTimes(Match MatchAlgorithm, string[] patterns, string text)
        {
            algorithm = MatchAlgorithm.Method.DeclaringType.Name; //get the name of the algorithm
            runTimes = new TimeSpan[patterns.Length];
            runTimes = GetTimes(MatchAlgorithm, patterns, text);
            arraySizes = new int[patterns.Length];
            for (int i = 0; i < patterns.GetLength(0); i++)
            {
                arraySizes[i] = patterns[i].Length;
            }
        }

        /// <summary>
        /// Runs the selected algorithm on the passed strings, returns an array of timespans
        /// </summary>
        /// <param name="SortAlgorithm"></param>
        /// <param name="unsortedArray"></param>
        private TimeSpan[] GetTimes(Match MatchAlgorithm, string[] patterns, string text)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            for (int i = 0; i < patterns.Length; i++)
            {
                //create a copy of the array to that the underlying array is not changed
                //start the stopwatch
                sw.Start();
                sw.Restart();
                //DateTime start = DateTime.Now;
                //sort the array, don't worry about a return value
                MatchAlgorithm.Invoke(patterns[i], text);
                //DateTime stop = DateTime.Now;
                //stop the watch
                sw.Stop();
                //add the time to the counter
                runTimes[i] = sw.Elapsed;
                //int elapsed = stop.Subtract(start).Milliseconds;

            }

            return runTimes;
        }

        /// <summary>
        /// Runs the selected algorithm on the passed arrays, returns an array of timespans
        /// </summary>
        /// <param name="SortAlgorithm"></param>
        /// <param name="unsortedArray"></param>
        private TimeSpan[] GetTimes(Sort SortAlgorithm, int[][] unsortedArrays)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            for (int i = 0; i < unsortedArrays.GetLength(0); i++)
            {
                //create a copy of the array to that the underlying array is not changed
                int[] tempArray = new int[unsortedArrays[i].Length];
                unsortedArrays[i].CopyTo(tempArray, 0);
                //start the stopwatch
                sw.Start();
                sw.Restart();
                //DateTime start = DateTime.Now;
                //sort the array, don't worry about a return value
                SortAlgorithm.Invoke(tempArray);
                //DateTime stop = DateTime.Now;
                //stop the watch
                sw.Stop();
                //add the time to the counter
                runTimes[i] = sw.Elapsed;
                //int elapsed = stop.Subtract(start).Milliseconds;

            }

            return runTimes;
        }
    }
}
